﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using Forms = System.Windows.Forms;
using System.Windows;
using System.Runtime.InteropServices;
using WindowsInput;
using System.Diagnostics;
using VKeyboard;
using Kinect_Interface_Prototype_1.Mouse_Control;
using System.Timers;
using Gesture_Control.Keyboard;
namespace Kinect_Interface_Prototype_1.Gesture_Control
{
    public class GestureControl
    {
        [DllImport("user32.dll")]
        static public extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        private const int SC_CLOSE = 0xF060;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_SHOWNORMAL = 1;
        public static int isKeyboardUp = 0;
        public static int windowKeyPressed = 0;
        public static KeyboardCover vk = new KeyboardCover();

        private StartupProgram MainProgram;
        private GestureTimer gestureTimer = new GestureTimer(700, 300, 1000);
        private GestureTimer handSwippingGestureTimer = new GestureTimer(1000, 300, 1000);
        private GestureTimer maximizeGestureTimer = new GestureTimer(1000, 300, 1000);

        private static Shell32.Shell shellInterface = new Shell32.Shell();

        public GestureControl(StartupProgram program)
        {
            MainProgram = program;
        }

        public void DetermineGestures(bool mouseGesturesActive, bool gesturesActive, float minDepth, bool inStartGesture, bool inLeftClick,
                                      bool inUpperRectangle, bool inRightClick, bool inRightHandSwipe, HandInside handInRightHandSwipe,
                                      bool inLeftHandSwipe, HandInside handInLeftHandSwipe, bool inCenterRectangle, HandInside handInCenter,
                                      bool inLowerLeftRectangle, HandInside HandInLowerLeftRectangle, bool inUpperRightRectangle, HandInside HandInUpperRightRectangle)
        {
            if (minDepth > 1000)
            {
                DetermineLeftHandGesture(mouseGesturesActive, gesturesActive, inStartGesture, inLeftClick, inUpperRectangle,
                                         inRightClick, inRightHandSwipe, handInRightHandSwipe, inLeftHandSwipe, handInLeftHandSwipe,
                                         inCenterRectangle, handInCenter, inLowerLeftRectangle, HandInLowerLeftRectangle,
                                         inUpperRightRectangle, HandInUpperRightRectangle);
                
            }
        }

        public void UpdateVirtualKeyboard(Joint leftHand, Joint rightHand)
        {
            if (isKeyboardUp == 1)
            {
                vk.setLeftHandPosition(leftHand);
                vk.setRightHandPosition(rightHand);
            }
        }

        private void DetermineLeftHandGesture(bool mouseGesturesActive, bool gesturesActive, bool inStartGesture, bool inLeftClick, bool inUpperRectangle, bool inRightClick,
                                              bool inRightHandSwipe, HandInside handInRightHandSwipe, bool inLeftHandSwipe, HandInside handInLeftHandSwipe,
                                              bool inCenterRectangle, HandInside handInCenter, bool inLowerLeftRectangle, HandInside HandInLowerLeftRectangle,
                                              bool inUpperRightRectangle, HandInside HandInUpperRightRectangle)
        {
            #region Initial Gesture Start

            // Initial state (returns here if no gestures are being performed)
            if (!inLeftClick && gestureTimer.HandClickState == HandClickState.NotReady)
            {
                ShowInitialGestureRectangles();
            }

            // If in the start gesture box and no timer is running
            if (inStartGesture && !gestureTimer.TimerIsRunning)
            {
                gestureTimer.WaitTimerStart(HandClickState.WaitingStartRectangle, 1);
            }

            // If the start gesture box was left before the waiting had finished, cancel the wait
            if (!inStartGesture && gestureTimer.HandClickState == HandClickState.WaitingStartRectangle)
            {
                gestureTimer.WaitCanceled();
            }

            // If the still in the start gesture box after the waiting has finished, move into a gesture ready state
            if (inStartGesture && gestureTimer.HandClickState == HandClickState.WaitFinishedStartRectangle)
            {
                ShowGestureRectangles();
                gestureTimer.HandClickState = HandClickState.HandInGestureReady;
            }

            // After moving out of the start gesture box start the timer to get to the next gesture box
            if (!inStartGesture && gestureTimer.HandClickState == HandClickState.HandInGestureReady)
            {
                gestureTimer.Reset();
                gestureTimer.Start(); // puts HandClickState equal to HandClickState.Ready
            }

            #endregion

            if (mouseGesturesActive)
            {
                #region Left Click

                //*** Left Click
                if (inLeftClick && gestureTimer.HandClickState != HandClickState.HandInLeftClick)
                {
                    gestureTimer.Stop();

                    ShowLeftGestureRectangle();

                    gestureTimer.HandClickState = HandClickState.HandInLeftClick;
                    //MessageBox.Show("Left Down");
                    MouseControl.SendDown();
                }

                // Send up after leaving left click rectangle
                if (!inLeftClick && gestureTimer.HandClickState == HandClickState.HandInLeftClick)
                {
                    gestureTimer.HandClickState = HandClickState.NotReady;

                    ShowInitialGestureRectangles();
                    //MessageBox.Show("Left Up");
                    MouseControl.SendUp();
                }
                //***
                #endregion

                #region Right Click

                //*** Right Click
                if (inRightClick && gestureTimer.HandClickState == HandClickState.Ready)
                {
                    ShowGestureStartRectangle();

                    gestureTimer.Restart();
                    gestureTimer.HandClickState = HandClickState.HandRightClick;
                }

                if (inStartGesture && gestureTimer.HandClickState == HandClickState.HandRightClick)
                {
                    gestureTimer.Stop();
                    //MessageBox.Show("Right Click");
                    MouseControl.SendRightClick();
                }
                // ***
                #endregion
            }

            #region Upper Gesture Rectangle (Double Click and Windows Switcher) (Mouse and Gestures)

            //*** Upper Gesture Rectangle (Double Click and Windows Switcher)
            if (inUpperRectangle && gestureTimer.HandClickState == HandClickState.Ready)
            {
                ShowGestureStartAndUpRectangle();

                gestureTimer.Stop();
                gestureTimer.WaitTimerStart(HandClickState.WaitingUpperRectangle, 2);
            }

            if (!inUpperRectangle && gestureTimer.HandClickState == HandClickState.WaitingUpperRectangle)
            {
                gestureTimer.WaitCanceled();

                gestureTimer.Start();
                gestureTimer.HandClickState = HandClickState.HandLeavingUp;
            }

            if (gesturesActive)
            {
                if (inUpperRectangle && gestureTimer.HandClickState == HandClickState.WaitFinishedUpperRectangle)
                {
                    ShowGestureUpRectangle(); // also will need to show swipe rectangles
                    gestureTimer.HandClickState = HandClickState.HandInUp;

                    // Show Windows switcher
                    //MessageBox.Show("Windows Switcher");
                    //shellInterface.WindowSwitcher();
                    InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LWIN);
                    InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.TAB);
                }

                if (!inUpperRectangle && gestureTimer.HandClickState == HandClickState.HandInUp)
                {
                    // Deactivate Windows switcher
                    InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LWIN);
                    gestureTimer.Reset();
                }
            }

            if (mouseGesturesActive)
            {
                if (inStartGesture && gestureTimer.HandClickState == HandClickState.HandLeavingUp)
                {
                    gestureTimer.Stop();
                    //MessageBox.Show("Double Click");
                    MouseControl.SendDoubleClick();
                }
            }
            // ***
            #endregion

            if (gesturesActive)
            {
                #region Right Hand Swipe for Windows Switcher
                // *** Right Hand Swipe for Windows Switcher (Only active if gestureTimer.HandClickState == HandClickState.HandInUp)
                if (inUpperRectangle && gestureTimer.HandClickState == HandClickState.HandInUp)
                {
                    if (inRightHandSwipe && handInRightHandSwipe == HandInside.Right)
                    {
                        handSwippingGestureTimer.Start();
                        handSwippingGestureTimer.HandClickState = HandClickState.RightHandInSwipeRectangle;
                    }

                    if (!inRightHandSwipe && handSwippingGestureTimer.HandClickState == HandClickState.RightHandInSwipeRectangle)
                    {
                        handSwippingGestureTimer.Start();
                        handSwippingGestureTimer.HandClickState = HandClickState.RightHandSwipping;
                    }

                    if (inLeftHandSwipe && handInLeftHandSwipe == HandInside.Right && handSwippingGestureTimer.HandClickState == HandClickState.RightHandSwipping)
                    {
                        handSwippingGestureTimer.Stop();
                        InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.TAB);
                    }
                }
                // ***
                #endregion

                #region PowerPoint and MediaPlayer Gestures
                // *** Power Point Right and Left hand swipe
                IntPtr foregroundWindow = GetForegroundWindow();
                bool powerpointActive = Process.GetProcessesByName("POWERPNT").Where(x => x.MainWindowHandle == foregroundWindow).Any();

                bool mediaPlayerAcitve = MainProgram.MediaPlayer_IsOpen() ? MainProgram.MediaPlayer_Handle() == foregroundWindow : false;

                if ((powerpointActive || mediaPlayerAcitve) && gestureTimer.HandClickState != HandClickState.HandInUp)
                {
                    #region Right Hand Swipe PowerPoint or MediaPlayer

                    if (inRightHandSwipe && handInRightHandSwipe == HandInside.Right && handSwippingGestureTimer.HandClickState == HandClickState.NotReady)
                    {
                        handSwippingGestureTimer.Start();
                        handSwippingGestureTimer.HandClickState = HandClickState.RightHandInSwipeRectangle;
                    }

                    if (!inRightHandSwipe && handSwippingGestureTimer.HandClickState == HandClickState.RightHandInSwipeRectangle)
                    {
                        handSwippingGestureTimer.Start();
                        handSwippingGestureTimer.HandClickState = HandClickState.RightHandSwipping;
                    }

                    if (inLeftHandSwipe && handInLeftHandSwipe == HandInside.Right && handSwippingGestureTimer.HandClickState == HandClickState.RightHandSwipping)
                    {
                        handSwippingGestureTimer.Stop();
                        if (powerpointActive) InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.RIGHT);
                        else if (mediaPlayerAcitve) MainProgram.MediaPlayer_NextLibraryPage();
                    }
                    #endregion

                    #region Left Hand Swipe PowerPoint or MediaPlayer

                    if (inLeftHandSwipe && handInLeftHandSwipe == HandInside.Left && handSwippingGestureTimer.HandClickState == HandClickState.NotReady)
                    {
                        handSwippingGestureTimer.Start();
                        handSwippingGestureTimer.HandClickState = HandClickState.LeftHandInSwipeRectangle;
                    }

                    if (!inLeftHandSwipe && handSwippingGestureTimer.HandClickState == HandClickState.LeftHandInSwipeRectangle)
                    {
                        handSwippingGestureTimer.Start();
                        handSwippingGestureTimer.HandClickState = HandClickState.LeftHandSwipping;
                    }

                    if (inRightHandSwipe && handInRightHandSwipe == HandInside.Left && handSwippingGestureTimer.HandClickState == HandClickState.LeftHandSwipping)
                    {
                        handSwippingGestureTimer.Stop();
                        if (powerpointActive) InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.LEFT);
                        else if (mediaPlayerAcitve) MainProgram.MediaPlayer_PreviousLibraryPage();
                    }

                    #endregion
                }

                #region PowerPoint Start Slide Show
                
                if (powerpointActive && inUpperRightRectangle && HandInUpperRightRectangle == HandInside.Right && gestureTimer.HandClickState == HandClickState.NotReady)
                {
                    gestureTimer.WaitTimerStart(HandClickState.WaitingPowerPointSlideShow, 2);
                }

                if (!inUpperRightRectangle && gestureTimer.HandClickState == HandClickState.WaitingPowerPointSlideShow)
                {
                    gestureTimer.WaitCanceled();
                }

                if (!inUpperRightRectangle && gestureTimer.HandClickState == HandClickState.WaitingFinishedPowerPointSlideShow)
                {
                    gestureTimer.Reset();
                }

                if (powerpointActive && inUpperRightRectangle && HandInUpperRightRectangle == HandInside.Right && gestureTimer.HandClickState == HandClickState.WaitingFinishedPowerPointSlideShow)
                {
                    gestureTimer.Reset();
                    InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.F5);
                }
                #endregion

                // ***
                #endregion

                #region Minimize Window
                
                // If in the lower left and upper right gesture box and no timer is running
                if (inLowerLeftRectangle && HandInLowerLeftRectangle == HandInside.Left && inUpperRightRectangle && HandInUpperRightRectangle == HandInside.Right && !gestureTimer.TimerIsRunning)
                {
                    gestureTimer.WaitTimerStart(HandClickState.WaitingMinimize, 1);
                }

                // If the lower left or upper right gesture box was left before the waiting had finished, cancel the wait
                if ((!inLowerLeftRectangle || !inUpperRightRectangle) && gestureTimer.HandClickState == HandClickState.WaitingMinimize)
                {
                    gestureTimer.WaitCanceled();
                }

                // If the still in the lower left and upper right gesture box after the waiting has finished, move into a gesture ready state
                if (inLowerLeftRectangle && HandInLowerLeftRectangle == HandInside.Left && inUpperRightRectangle && HandInUpperRightRectangle == HandInside.Right
                    && gestureTimer.HandClickState == HandClickState.WaitFinishedMinimize)
                {
                    ShowCenterGestureRectangle();
                    gestureTimer.HandClickState = HandClickState.MinimizeReady;
                }

                // After moving out of the lower left or upper right gesture box start the timer to get to the next gesture box
                if ((!inLowerLeftRectangle || !inUpperRightRectangle) && gestureTimer.HandClickState == HandClickState.MinimizeReady)
                {
                    gestureTimer.Reset();
                    gestureTimer.Start(); // puts HandClickState equal to HandClickState.Ready, so we reset below
                    gestureTimer.HandClickState = HandClickState.MinimizeTimerRunning;
                }

                if (inCenterRectangle && handInCenter == HandInside.Both && gestureTimer.HandClickState == HandClickState.MinimizeTimerRunning)
                {
                    gestureTimer.Stop();
                    //MessageBox.Show("Minimize");

                    IntPtr hWnd = GetForegroundWindow();
                    // Prevents minimizing App Dock, Control Form, and keyboard
                    if (!hWnd.Equals(IntPtr.Zero) && !hWnd.Equals(MainProgram.AppDock_Handle()) && !hWnd.Equals(MainProgram.ControlForm_Handle()) && !hWnd.Equals(MainProgram.VirtualKeyboard_Handle()))
                    {
                        ShowWindowAsync(hWnd, SW_SHOWMINIMIZED);
                    }
                }
                #endregion

                #region Maximize Window

                // If in the lower left and upper right gesture box and no timer is running
                if (inCenterRectangle && handInCenter == HandInside.Both && !maximizeGestureTimer.TimerIsRunning)
                {
                    maximizeGestureTimer.WaitTimerStart(HandClickState.WaitingMaximize, 1);
                }

                // If the lower left or upper right gesture box was left before the waiting had finished, cancel the wait
                if (!inCenterRectangle && maximizeGestureTimer.HandClickState == HandClickState.WaitingMaximize)
                {
                    maximizeGestureTimer.WaitCanceled();
                }

                // If the still in the lower left and upper right gesture box after the waiting has finished, move into a gesture ready state
                if (inCenterRectangle && handInCenter == HandInside.Both && maximizeGestureTimer.HandClickState == HandClickState.WaitFinishedMaximize)
                {
                    ShowCenterGestureRectangle();
                    maximizeGestureTimer.HandClickState = HandClickState.MaximizeReady;
                }

                // After moving out of the lower left or upper right gesture box start the timer to get to the next gesture box
                if (!inCenterRectangle && maximizeGestureTimer.HandClickState == HandClickState.MaximizeReady)
                {
                    maximizeGestureTimer.Reset();
                    maximizeGestureTimer.Start(); // puts HandClickState equal to HandClickState.Ready, so we reset below
                    maximizeGestureTimer.HandClickState = HandClickState.MaximizeTimerRunning;
                }

                if (inLowerLeftRectangle && HandInLowerLeftRectangle == HandInside.Left && inUpperRightRectangle && HandInUpperRightRectangle == HandInside.Right
                    && maximizeGestureTimer.HandClickState == HandClickState.MaximizeTimerRunning)
                {
                    maximizeGestureTimer.Stop();
                    //MessageBox.Show("Maximize");

                    IntPtr hWnd = GetForegroundWindow();
                    // Prevents maximizing App Dock, Control Form, and keyboard
                    if (!hWnd.Equals(IntPtr.Zero) && !hWnd.Equals(MainProgram.AppDock_Handle()) && !hWnd.Equals(MainProgram.ControlForm_Handle()) && !hWnd.Equals(MainProgram.VirtualKeyboard_Handle()))
                    {
                        ShowWindowAsync(hWnd, SW_SHOWMAXIMIZED);
                    }
                }
                #endregion
            }

            if (gesturesActive || isKeyboardUp == 1)
            {
                #region Center Gesture Rectangle (Open Keyboard)

                // If in the center gesture box and no timer is running
                if (inCenterRectangle && !gestureTimer.TimerIsRunning)
                {
                    gestureTimer.WaitTimerStart(HandClickState.WaitingCenterRectangle, 2); // waits 1 second
                }
                // If the center gesture box was exited before the waiting had finished, cancel the wait
                if (!inCenterRectangle && gestureTimer.HandClickState == HandClickState.WaitingCenterRectangle)
                {
                    gestureTimer.WaitCanceled();
                }

                if (inCenterRectangle && gestureTimer.HandClickState == HandClickState.WaitFinishedCenterRectangle)
                {
                    ShowSwipeGestureRectangles();
                    gestureTimer.HandClickState = HandClickState.HandInCenterReady;
                }

                // After moving out of the start gesture box start the timer to get to the next gesture box
                if (!inCenterRectangle && gestureTimer.HandClickState == HandClickState.HandInCenterReady)
                {
                    gestureTimer.Reset();
                    gestureTimer.Start(); // puts HandClickState equal to HandClickState.Ready
                    gestureTimer.HandClickState = HandClickState.HandInCenterTimmerRunning;
                }

                if (inLeftHandSwipe && handInLeftHandSwipe == HandInside.Left && inRightHandSwipe && handInRightHandSwipe == HandInside.Right
                    && gestureTimer.HandClickState == HandClickState.HandInCenterTimmerRunning)
                {
                    gestureTimer.Stop();
                    ShowGestureRectangles();
                    //MessageBox.Show("Keyboard Open");

                    if (isKeyboardUp == 1)
                        MainProgram.VirtualKeyboard_Hide();
                    else
                        MainProgram.VirtualKeyboard_Show();
                }
                #endregion
            }
        }

        #region Show Rectangle Functions

        private void ShowGestureRectangles()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.CenterGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftHandSwipeGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightHandSwipeGestureRectangle, true);
        }

        private void ShowLeftGestureRectangle()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, false);
        }

        private void ShowGestureStartRectangle()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, false);
        }

        private void ShowGestureStartAndUpRectangle()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, true);
        }

        private void ShowGestureUpRectangle()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, true);
        }

        private void ShowInitialGestureRectangles()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.CenterGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftHandSwipeGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightHandSwipeGestureRectangle, true);
        }

        private void ShowSwipeGestureRectangles()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.CenterGestureRectangle, false);
        }

        private void ShowCenterGestureRectangle()
        {
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.StartGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightClickGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.UpperGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.CenterGestureRectangle, true);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.LeftHandSwipeGestureRectangle, false);
            MainProgram.KinectForm_ToggleActiveGestureRectangle(GestureRectangleType.RightHandSwipeGestureRectangle, false);
        }

        #endregion
    }

    public class GestureTimer
    {
        public HandClickState HandClickState { get; set; }
        public Timer Timer;
        public Timer WaitTimer;
        public Timer WaitTimer2;
        private int Interval;
        private int WaitInterval;

        private bool timerIsRunning;
        public bool TimerIsRunning { get { return timerIsRunning; } }

        private int waitTimerInUse = 1;

        public GestureTimer(int interval, int waitInterval, int secondaryWaitInterval)
        {
            Interval = interval;
            WaitInterval = waitInterval;

            Timer = new Timer { Interval = interval, AutoReset = false };
            WaitTimer = new Timer { Interval = waitInterval, AutoReset = false };
            WaitTimer2 = new Timer { Interval = secondaryWaitInterval, AutoReset = false };

            Timer.Elapsed += new ElapsedEventHandler(gestureTimer_Elapsed);
            WaitTimer.Elapsed += new ElapsedEventHandler(waitTimer_Elapsed);
            WaitTimer2.Elapsed += new ElapsedEventHandler(waitTimer_Elapsed);

            HandClickState = HandClickState.NotReady;
            timerIsRunning = false;
        }

        public void Start()
        {
            HandClickState = HandClickState.Ready;
            Timer.Start();
            timerIsRunning = true;
        }

        public void Stop()
        {
            HandClickState = HandClickState.NotReady;
            timerIsRunning = false;
            Timer.Stop();
        }

        public void Restart()
        {
            Timer.Stop();
            Timer.Start();
            timerIsRunning = true;
        }

        // Wait timer with specified interval
        public void WaitTimerStart(HandClickState state, int waitTimer)
        {
            waitTimerInUse = waitTimer;

            if (waitTimerInUse == 1)
                WaitTimer.Start();
            else if (waitTimerInUse == 2)
                WaitTimer2.Start();

            HandClickState = state;
            timerIsRunning = true;
        }

        public void WaitCanceled()
        {
            if (waitTimerInUse == 1)
                WaitTimer.Stop();
            else if (waitTimerInUse == 2)
                WaitTimer2.Stop();

            HandClickState = HandClickState.NotReady;
            timerIsRunning = false;
        }

        public void Reset()
        {
            HandClickState = HandClickState.NotReady;
            timerIsRunning = false;
        }

        private void gestureTimer_Elapsed(object sender, EventArgs e)
        {
            Stop();
        }

        private void waitTimer_Elapsed(object sender, EventArgs e)
        {
            if (HandClickState == HandClickState.WaitingStartRectangle)
                HandClickState = HandClickState.WaitFinishedStartRectangle;
            else if (HandClickState == HandClickState.WaitingUpperRectangle)
                HandClickState = HandClickState.WaitFinishedUpperRectangle;
            else if (HandClickState == HandClickState.WaitingCenterRectangle)
                HandClickState = HandClickState.WaitFinishedCenterRectangle;
            else if (HandClickState == HandClickState.WaitingMinimize)
                HandClickState = HandClickState.WaitFinishedMinimize;
            else if (HandClickState == HandClickState.WaitingMaximize)
                HandClickState = HandClickState.WaitFinishedMaximize;
            else if (HandClickState == HandClickState.WaitingPowerPointSlideShow)
                HandClickState = HandClickState.WaitingFinishedPowerPointSlideShow;
            else
            {
                HandClickState = HandClickState.NotReady;
                timerIsRunning = false;
            }
            ((Timer)sender).Stop();
        }
    }

    public enum HandClickState
    {
        NotReady,
        Ready,
        HandDouble,
        HandRightClick,
        HandLeftClick,
        WaitingStartRectangle,
        WaitingUpperRectangle,
        WaitFinishedStartRectangle,
        WaitFinishedUpperRectangle,
        HandInGestureReady,
        HandInLeftClick,
        HandLeavingUp,
        HandInUp,
        RightHandInSwipeRectangle,
        RightHandSwipping,
        LeftHandInSwipeRectangle,
        LeftHandSwipping,
        WaitingCenterRectangle,
        WaitFinishedCenterRectangle,
        HandInCenterReady,
        WaitingMinimize,
        WaitFinishedMinimize,
        MinimizeReady,
        MinimizeTimerRunning,
        HandInCenterTimmerRunning,
        WaitingMaximize,
        WaitFinishedMaximize,
        MaximizeTimerRunning,
        MaximizeReady,
        WaitingPowerPointSlideShow,
        WaitingFinishedPowerPointSlideShow
    }
}
        
    
        //***************************************************************

        /*
        public void DetermineAction(Point leftHandPoint, Point rightHandPoint, Joint rightHand, Joint leftHand)
        {
            if (isKeyboardUp == 0)
            {
                checkWindowsAltKey(leftHandPoint);

                rightHandWatcherIn.DetermineHandAction(leftHandPoint, rightHandPoint);
                leftHandWatcherIn.DetermineHandAction(leftHandPoint, rightHandPoint);
                rightHandWatcher.DetermineTwoHandAction(rightHandPoint, leftHandPoint);
                leftHandWatcher.DetermineTwoHandAction(rightHandPoint, leftHandPoint);
                rightHandWatcherLeft.DetermineHandAction(rightHandPoint);
               
            }
            else if (isKeyboardUp == 1)
            {
                vk.setLeftHandPosition(leftHand);
                vk.setRightHandPosition(rightHand);
            }
        }

        public void checkWindowsAltKey(Point leftHandPoint)
        {
            if (startTimer)
            {
                timer++;
            }

            if (leftHandPoint.Y < 60)
            {
                if (!startTimer)
                {
                    timer = 0;
                    startTimer = true;

                }
            }
            else
            {
                startTimer = false;
            }

            if (leftHandPoint.Y < 60 && timer > 75)
            {
                
                if (tabPress == 0)
                {
                    InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LWIN);
                    InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.TAB);
                    tabPress = 1;
                    windowKeyPressed = 1;
                   
                }
         
            }
            else
            {
                InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LWIN);
                tabPress = 0;
                windowKeyPressed = 0;
                //startTimer = false;
                
            }
          
        }

  
        private class HandWatcher
        {
            private bool startTimer = false;
            private int timer = 0;
            int tabpressHW = 0;
            private string keyboardAction;
            private string swipeDirection;
            private int startingThreshold;
            private int endingThreshold;
            public IntPtr hWnd = GetForegroundWindow();
           
           
            public HandWatcher(string keyboardAction, int startingThreshold, int endingThreshold, string swipeDirection)
            {
                this.keyboardAction = keyboardAction;
                this.startingThreshold = startingThreshold;
                this.endingThreshold = endingThreshold;
                this.swipeDirection = swipeDirection;
            }

            public void DetermineHandAction(Point lhandPoint, Point rhandPoint)
            {
               
                 if (startTimer)
                {
                    timer++;
                }


                 if (lhandPoint.X < 160 && lhandPoint.Y < 95 && rhandPoint.X > 190 && rhandPoint.Y >= 160)
                {
                    if (!startTimer)
                    {
                        startTimer = true;
                        
                    }
                 
                }

                if (lhandPoint.Y > 100 && lhandPoint.X > 175 && rhandPoint.X < 300 && rhandPoint.Y < 150 && startTimer && timer < 75 )
                    
                {
                    hWnd = GetForegroundWindow();
                    if (!hWnd.Equals(IntPtr.Zero))
                    {

                      ShowWindowAsync(hWnd, SW_SHOWMINIMIZED);
                    }
                    startTimer = false;
                    timer = 0;
             
                }

                if (lhandPoint.Y > 100 && lhandPoint.X > 175 && rhandPoint.X < 300 && rhandPoint.Y < 150)
                {
                    if (!startTimer)
                    {
                        startTimer = true;

                    }
                }

                if (  lhandPoint.X < 160 && lhandPoint.Y < 95 && rhandPoint.X > 190 && rhandPoint.Y > 160 && startTimer && timer <75 )
                {
                    if (!hWnd.Equals(IntPtr.Zero))
                    {
                        ShowWindowAsync(hWnd, SW_SHOWMAXIMIZED);
                        timer = 0;
                        startTimer = false;
                    }

                   
                }


                if (timer >= 75)
                {
                    startTimer = false;
                    timer = 0;
                    
                }
               
            }

            public void DetermineTwoHandAction(Point lhandPoint, Point rhandPoint)
            {
                 
                if (startTimer)
                {
                    timer++;
                }

                if (rhandPoint.X > 200 && rhandPoint.X < 250 && lhandPoint.X > 200 && lhandPoint.X < 250 && lhandPoint.Y > 180 && rhandPoint.Y > 180)
                {
                    if (!startTimer)
                    {
                        startTimer = true;

                    }
                    
                }

                if (lhandPoint.X > 325 && rhandPoint.X < 125 && lhandPoint.Y > 180 && rhandPoint.Y > 180 && timer < 35) 
                {
                   
                        if (isKeyboardUp == 0)
                        {
                            System.Threading.Thread.Sleep(500);
                            isKeyboardUp = 1;
                            vk.Show();
                        }
                   
                    startTimer = false;
                    timer = 0;

                }

                if (determineUpperThreshold(lhandPoint) && determineUpperThreshold(rhandPoint))
                {
                    if (!startTimer)
                    {
                        startTimer = true;
                    }
                }

                if (determineLowerThreshold(rhandPoint) && determineLowerThreshold(lhandPoint) && startTimer && timer < 50)
                {

                    if (swipeDirection == "down")
                    {

                        if (!hWnd.Equals(IntPtr.Zero))
                        {
                           ShowWindowAsync(hWnd, SW_SHOWNORMAL);
                        }
                        startTimer = false;
                        timer = 0;
                    }

                }


                
            }
            public void DetermineHandAction(Point handPoint)
            {
                if (startTimer)
                {
                    timer++;
                }

                if (determineUpperThreshold(handPoint))
                {
                    if (!startTimer)    
                    {
                        startTimer = true;
                    }
                }

                if (determineLowerThreshold(handPoint) && startTimer && timer < 40 )
                {
                    
                   if (swipeDirection == "left")
                    {   
                       if (windowKeyPressed == 1 && tabpressHW == 0)
                        {
                            InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.TAB);
                            tabpressHW = 1;
                            timer = 0;
                        }
                      
                       

                    }
                }
                if (timer >= 40)
                {
                    startTimer = false;
                    timer = 0;
                    tabpressHW = 0;

                }

               
            }

            private bool determineUpperThreshold(Point handPoint)
            {
                if (swipeDirection == "down")
                    return handPoint.Y < startingThreshold;
                else if (swipeDirection == "up")
                    return handPoint.Y >= endingThreshold;
                else if (swipeDirection == "left")
                    return handPoint.X > startingThreshold;
                else
                    return handPoint.X > startingThreshold;
            }

            private bool determineLowerThreshold(Point handPoint)
            {
                if (swipeDirection == "down")
                    return handPoint.Y > endingThreshold;
                else if (swipeDirection == "up")
                    return handPoint.Y <= endingThreshold;
                else if (swipeDirection == "left")
                    return handPoint.X < endingThreshold;
                else
                    return handPoint.X > startingThreshold;
            }
        }
          
    }
     
}
    */